<html>
    <head>
        <title>导言</title>
    </head>
    <body>
        <script>
            /*
                        二、用法

                                ★、并发戳 IHasConcurrencyStamp 接口

                                         1、实体实现 IHasConcurrencyStamp 接口，ABP会自动处理并发戳。

                                         
                                                    要为你的实体启用"并发控制"，你应该直接或间接实现 IConcurrencyStamp(并发戳) 接口。

                                                        eg:
                                                                // 并发戳接口：  (主要就是要有一个 ConcurrencyStamp 属性)
                                                                public interface IHasConcurrencyStamp 
                                                                {
                                                                    public string ConcurrencyStamp { get; set; }
                                                                }

                                                    它是"并发控制"的基本接口，只有一个名为  ConcurrencyStamp 的简单属性。

                                                    当一个新记录正在创建时，如果实体实现了 IHasConcurrencyStamp ，ABP会自动为 ConcurrencyStamp 属性生成一个唯一值。

                                                    当记录正在更新时，ABP会将实体的 ConcurrencyStamp 属性 与用户提供的 ConcurrencyStamp 值进行比较，

                                                    如果值匹配，它会自动使用新的唯一值更新 ConcurrencyStamp 属性。

                                                    如果不匹配，则抛出AbpDbConcurrencyException异常。

                                            

                                        2、工作单元中自动获取并发戳：

                                                    如果有工作单元，则需要在创建或更新时调用  SaveChangeAsync 方法"获取生成的ConcurrencyStamp".


                                                        eg:  为图书实体应用并发控制

                                                                // 为实体实现 IHasConcurrencyStamp 接口：
                                                                public class Book : Entity<Guid>, IHasConcurrencyStamp
                                                                {
                                                                    // 只要你有这个属性，ABP就会自动处理并发戳。
                                                                    public string ConcurrencyStamp { get; set; }
                                                                }


                                       3、 输入Dto、输出Dto 也应该实现 IHasConcurrencyStamp 接口，包含ConcurrencyStamp 属性。
        
                                                    你也可以让输入、输出DTO实现 IHasConcurrencyStamp 接口，这样你就可以在创建或更新实体时传递并发戳。

                                               eg:
                                                    // 输出Dto
                                                    public class BookDto : EntityDto<Guid>, IHasConcurrencyStamp 
                                                    {
                                                        // 其他属性

                                                        public string ConcurrencyStamp { get; set; }
                                                    }

                                                    // 输入Dto
                                                    public class UpdateBookDto : IHasConcurrencyStamp 
                                                    {
                                                        // 其他属性

                                                        public string ConcurrencyStamp { get; set; }
                                                    }


                                       4、在应用程序服务中自动获取并发戳：

                                                    在应用程序服务中的UpdateAsync方法中将 ConloccyStamp 输入值设置为实体的ConcurrencyStamp属性值，
                                            eg:
                                                    public class BookAppService : ApplicationService, IBookAppService 
                                                    {
                                                        //...

                                                        public virtual async Task<BookDto> UpdateAsync(Guid id, UpdateBookDto input) 
                                                        {
                                                            var book = await BookRepository.GetAsync(id);

                                                            book.ConcurrencyStamp = input.ConcurrencyStamp;

                                                            // 跟新其他属性...
                                                           
                                                            await BookRepository.UpdateAsync(book, autoSave: true);  // 使用 autoSave: true 来获取实体最新的ConcurrencyStamp
                                                        }
                                                    }

                                        上述流程之后，当多个用户尝试同时更新用一个记录时，会发生并发出哦不匹配的情况，并抛出 AbpDbConcurrencyException 异常。
                    */

        </script>
    </body>
</html>